package basic

import (
	"fmt"
	"golang.org/x/net/netutil"
	"log"
	"net"
	"net/http"
	"strings"
	"time"
)

/***
Printf,Sprintf , Fprintf 区别?

Printf 直接输出到 os.Stdout
Sprintf 可以赋值给一个变量     s:=fmt.Sprintf("a %s","string")
Fprintf 输出到 os.Writers 里面


*/

var serveMux *http.ServeMux = http.NewServeMux()

// 注册访问路由
func HandleFunc(pattern string, handler func(w http.ResponseWriter, r *http.Request)) {
	serveMux.HandleFunc(pattern, handler)
}

func Handle(pattern string, handler http.Handler) {
	serveMux.Handle(pattern, handler)
}

// 启动 HTTP 服务
// start http server
func RunHttp(add string) {
	// 配置
	server := http.Server{
		Addr:              add,
		Handler:           serveMux,        // Handle
		ReadTimeout:       5 * time.Second, // 读超时
		WriteTimeout:      5 * time.Second, // 写超时
		ReadHeaderTimeout: 5 * time.Second,
		IdleTimeout:       5 * time.Second,
	}

	// 启动监听(设置并发数)
	l, err := net.Listen("tcp", add)
	if err != nil {
		log.Fatalf("Listen: %v", err)
	}
	defer l.Close()
	l = netutil.LimitListener(l, 2) // 设置并发数量为 2
	if err := server.Serve(l); err != nil {
		log.Fatal(err)
	}

	//// 启动监听(默认启动方式)
	//if err := server.ListenAndServe(); err != nil {
	//	log.Fatal(err)
	//}
}

// todo http://127.0.0.1:9090/?url_long=aaaa&url_long=bbbb
func sayhelloName(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	fmt.Println("=====")
	// 全部请求参数
	fmt.Println(r.Form)
	// 请求路径
	fmt.Println("path", r.URL.Path)

	fmt.Println("scheme", r.URL)
	// 获取请求参数
	fmt.Println(r.Form["url_long"])

	for k, v := range r.Form {
		fmt.Println("key:", k)
		fmt.Println("val:", strings.Join(v, ""))
	}
	// 模拟耗时操作
	time.Sleep(1 * time.Second)

	fmt.Fprintf(w, "Hello World")
}

// 注册访问路由
func InitRoute() {
	HandleFunc("/", sayhelloName)
}

// 默认启动方式
func defaultServer() {
	http.HandleFunc("/", sayhelloName)
	err := http.ListenAndServe("127.0.0.1:9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func startServer() {
	InitRoute()
	RunHttp(":9090")
}
